<?php
class HtmlDocument {
	protected $lang;
	protected $dir;
	protected $title;
	protected $stylesheets;
	protected $scripts;
	protected $metas;
	protected $references;
	protected $debug;
	protected $log;
	
	function __construct() {
		$this->lang = "en";
		$this->dir = "ltr";
		$this->title = "No Document Title";
		$this->stylesheets = array();
		$this->scripts = array();
		$this->metas = array();
		$this->references = array();
		$this->debug = false;
		$this->log = array();
		
		$this->Reference("host", "http".((isset($_SERVER['HTTPS']) && $_SERVER["HTTPS"]=="on")?"s":"")."://".$_SERVER['HTTP_HOST']);
	}
	
	function Reference($key, $value) {
		$key = "%".$key."%";
		if(!array_key_exists($key, $this->references)) {
			$this->references[$key]=$value;
		} else {
			if($this->debug) {
				$dbg = array_shift(debug_backtrace());
				$this->log []= "reference key $key was overriden at line {$dbg['line']} in {$dbg['file']}";
			}
			$this->references[$key]=$value;
		}
	}
	
	function Title($str = null) {
		if(!$str) { return $this->title; }
		$this->title = $str;
	}
	
	function Meta($attrs) {
		$this->metas []= $attrs;
	}
	
	function StyleSheet($path) {
		if(!in_array($path, $this->stylesheets)) {
			$this->stylesheets []= $path;
		} else {
			if($this->debug) {
				$dbg = array_shift(debug_backtrace());
				$this->log []= "failed to add stylesheet \"$path\" as it already exists at line {$dbg['line']} in {$dbg['file']}";
			}
		}
	}
	
	function Script($path) {
		if(!in_array($path, $this->scripts)) {
			$this->scripts []= $path;
		} else {
			if($this->debug) {
				$dbg = array_shift(debug_backtrace());
				$this->log []= "failed to add script \"$path\" as it already exists at line {$dbg['line']} in {$dbg['file']}";
			}
		}
	}
	
	function Debug($val = null) {
		if(!$val) { return $this->debug; }
		$this->debug = $val;
	}
	
	function Get() {
		// start time in ms
		$startTime = microtime(true);
	
		// initialize reference data
		$refKeys = array_keys($this->references);
		$refValues = array_values($this->references);
	
		// begin generating document
		$html = array();
		$html []= "<!DOCTYPE html>";
		$html []= "<html lang=\"{$this->lang}\" dir=\"{$this->dir}\">";
		// insert document title
		$html []= "<head>";
		$html []= "<title>{$this->title}</title>";
		// insert resources (stylesheets and scripts)
		foreach($this->stylesheets as $path) {
			$path = str_ireplace($refKeys, $refValues, $path);
			$html []= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$path\" />";
		}
		foreach($this->scripts as $path) {
			$path = str_ireplace($refKeys, $refValues, $path);
			$html []= "<script language=\"javascript\" type=\"text/javascript\" src=\"$path\" ></script>";
		}
		// insert meta tags
		foreach($this->metas as $metaAttributes) {
			$list = array();
			foreach($metaAttributes as $key => $value) {
				$list []= sprintf("%s=\"%s\"", $key, $value);
			}
			$html [] = str_ireplace($refKeys, $refValues, "<meta ".implode(" ", $list)." />");
		}
		$html []= "</head>";
		$html []= "</html>";
		if($this->debug) {
			// document generation duraction
			usleep(1); //-- otherwise time may be to close and give an invalid result
			$duration = microtime(true) - $startTime;
			$html []= "<!-- generated in $duration seconds -->";
			foreach($this->log as $log) {
				$html []= "<!-- $log -->";
			}
		}
		return implode(null, $html);
	}
};
?>